/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * This source code is licensed under the license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.share.model

import android.graphics.Bitmap
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable

/**
 * Describes a photo for sharing.
 *
 * Use [SharePhoto.Builder] to build instances
 */
class SharePhoto : ShareMedia<SharePhoto, SharePhoto.Builder> {
  /**
   * If the photo is resident in memory, this method supplies the data.
   *
   * @return [android.graphics.Bitmap] representation of the photo.
   */
  val bitmap: Bitmap?

  /**
   * The URL to the photo.
   *
   * @return [android.net.Uri] that points to a network location or the location of the photo on
   * disk.
   */
  val imageUrl: Uri?

  /**
   * Specifies whether the photo represented by this object was generated by the user or by the
   * application.
   *
   * @return Indication of whether the photo is user-generated.
   */
  val userGenerated: Boolean

  /**
   * Gets the user generated caption. Note that the 'caption' must come from the user, as pre-filled
   * content is forbidden by the Platform Policies (2.3).
   *
   * @return The user generated caption.
   */
  val caption: String?

  private constructor(builder: Builder) : super(builder) {
    bitmap = builder.bitmap
    imageUrl = builder.imageUrl
    userGenerated = builder.userGenerated
    caption = builder.caption
  }

  internal constructor(parcel: Parcel) : super(parcel) {
    bitmap = parcel.readParcelable(Bitmap::class.java.classLoader)
    imageUrl = parcel.readParcelable(Uri::class.java.classLoader)
    userGenerated = parcel.readByte().toInt() != 0
    caption = parcel.readString()
  }

  override fun describeContents(): Int = 0

  override fun writeToParcel(out: Parcel, flags: Int) {
    super.writeToParcel(out, flags)
    out.writeParcelable(bitmap, 0)
    out.writeParcelable(imageUrl, 0)
    out.writeByte((if (userGenerated) 1 else 0).toByte())
    out.writeString(caption)
  }

  override val mediaType: Type = Type.PHOTO

  /** Builder for the [com.facebook.share.model.SharePhoto] class. */
  class Builder : ShareMedia.Builder<SharePhoto, Builder>() {
    internal var bitmap: Bitmap? = null
      private set
    internal var imageUrl: Uri? = null
      private set
    internal var userGenerated = false
      private set
    internal var caption: String? = null
      private set

    /**
     * Sets the bitmap representation of the photo.
     *
     * @param bitmap [android.graphics.Bitmap] representation of the photo.
     * @return The builder.
     */
    fun setBitmap(bitmap: Bitmap?): Builder {
      this.bitmap = bitmap
      return this
    }

    /**
     * Sets the URL to the photo.
     *
     * @param imageUrl [android.net.Uri] that points to a network location or the location of the
     * photo on disk.
     * @return The builder.
     */
    fun setImageUrl(imageUrl: Uri?): Builder {
      this.imageUrl = imageUrl
      return this
    }

    /**
     * Sets whether the photo represented by this object was generated by the user or by the
     * application.
     *
     * @param userGenerated Indication of whether the photo is user-generated.
     * @return The builder.
     */
    fun setUserGenerated(userGenerated: Boolean): Builder {
      this.userGenerated = userGenerated
      return this
    }

    /**
     * Sets the user generated caption for the photo. Note that the 'caption' must come from the
     * user, as pre-filled content is forbidden by the Platform Policies (2.3).
     *
     * @param caption [java.lang.String] of a [com.facebook.share.model.SharePhoto]
     * @return The builder.
     */
    fun setCaption(caption: String?): Builder {
      this.caption = caption
      return this
    }

    override fun build(): SharePhoto {
      return SharePhoto(this)
    }

    override fun readFrom(model: SharePhoto?): Builder {
      return if (model == null) {
        this
      } else
          super.readFrom(model)
              .setBitmap(model.bitmap)
              .setImageUrl(model.imageUrl)
              .setUserGenerated(model.userGenerated)
              .setCaption(model.caption)
    }

    internal fun readFrom(parcel: Parcel): Builder {
      return this.readFrom(parcel.readParcelable(SharePhoto::class.java.classLoader))
    }

    companion object {
      /*
       * For backwards compatibility with SharePhotoContent.  Prefer ShareMediaContent for new
       * code.
       */
      internal fun writePhotoListTo(out: Parcel, parcelFlags: Int, photos: List<SharePhoto>) {
        val array = photos.toTypedArray()
        out.writeParcelableArray(array, parcelFlags)
      }

      /*
       * For backwards compatibility with SharePhotoContent.  Prefer ShareMediaContent for new
       * code.
       */
      internal fun readPhotoListFrom(parcel: Parcel): List<SharePhoto> {
        val media = readListFrom(parcel)
        return media.filterIsInstance<SharePhoto>()
      }
    }
  }

  companion object {
    @JvmField
    val CREATOR: Parcelable.Creator<SharePhoto> =
        object : Parcelable.Creator<SharePhoto> {
          override fun createFromParcel(source: Parcel): SharePhoto {
            return SharePhoto(source)
          }

          override fun newArray(size: Int): Array<SharePhoto?> {
            return arrayOfNulls(size)
          }
        }
  }
}
